package com.example.worklab.animation.widget

import android.animation.AnimatorSet
import android.animation.ObjectAnimator
import android.animation.TypeEvaluator
import android.content.Context
import android.graphics.PointF
import android.util.Log
import android.view.ViewGroup
import android.view.animation.AccelerateInterpolator
import android.view.animation.LinearInterpolator
import androidx.appcompat.widget.AppCompatImageView
import androidx.core.animation.addListener
import com.example.worklab.animation.utils.BezierUtils

class ShoppingView @JvmOverloads constructor(
    context: Context,
    attrs: android.util.AttributeSet? = null,
    defStyleAttr: Int = 0
) : AppCompatImageView(context, attrs, defStyleAttr) {
    private val TAG: String = "ShoppingView"

    // 缩放动画
    private var mScaleXAnimator: ObjectAnimator =
        ObjectAnimator.ofFloat(this, "scaleX", 1.0f, 0.8f).apply {
            duration = 200
            interpolator = AccelerateInterpolator()
        }
    private var mScaleYAnimator: ObjectAnimator =
        ObjectAnimator.ofFloat(this, "scaleY", 1.0f, 0.8f).apply {
            duration = 200
            interpolator = AccelerateInterpolator()
        }

    //旋转动画
    private var mRotateAnimator: ObjectAnimator =
        ObjectAnimator.ofFloat(this, "rotation", 0f, 35f).apply {
            duration = 100
            interpolator = LinearInterpolator()
        }

    //动画集合
    private var mAnimatorSet: AnimatorSet = AnimatorSet()

    //移动动画，需要自定义轨迹（估值器）
    private var mTranslateAnimator: ObjectAnimator? = null

    // 动画结束时回调
    var onAnimEnd: (() -> Unit)? = null

    /**
     * 开始动画
     * @param startPoint 起始点
     * @param endPointF  结束点
     */
    fun start(startPoint: PointF, endPointF: PointF) {
        // 先把view移动到起始位置
        setPosition(startPoint)
        // 创建View移动的动画，这里要通过动画修改position属性值，因此需要有setPosition()方法，并且方法要是public的
        mTranslateAnimator = ObjectAnimator.ofObject(
            this,
            "position",
            BezierEvaluator(startPoint, endPointF),
            startPoint,
            endPointF
        ).apply {
            duration = 450
            interpolator = AccelerateInterpolator()
        }

        //播放动画，先缩放，然后旋转，最后移动
        mAnimatorSet.apply {
            play(mScaleXAnimator)
                .with(mScaleYAnimator)
                .before(mRotateAnimator)
            play(mRotateAnimator)
                .before(mTranslateAnimator)
            addListener(
                onEnd = {
                    onAnimEnd?.invoke()
                    // 动画结束后，把这个View从DecorView里移除
                    val parent = this@ShoppingView.parent
                    if (parent != null && parent is ViewGroup) {
                        parent.removeView(this@ShoppingView)
                    }
                }
            )
        }.start()
    }

    /**
     * 动画过程中会调用该方法，修改position的值，从而实现动画效果
     */
    fun setPosition(position: PointF?) {
        if (position == null) {
            return
        }
        Log.i(TAG, "setPosition: $position")
        translationX = position.x
        translationY = position.y
    }

    /**
     * 自定义估值器，
     * 二阶贝塞尔轨迹
     */
    private class BezierEvaluator(
        startPoint: PointF,
        endPoint: PointF
    ) : TypeEvaluator<PointF> {
        private val TAG: String = "BezierEvaluator"
        private val pointList: MutableList<PointF> = mutableListOf()

        init {
            // 控制点
            val controlPoint = PointF(endPoint.x, startPoint.y)

            pointList.add(startPoint)
            pointList.add(controlPoint)
            pointList.add(endPoint)
        }

        override fun evaluate(fraction: Float, startValue: PointF?, endValue: PointF?): PointF {
            Log.i(TAG, "evaluate: fraction = $fraction")
            return PointF(
                BezierUtils.calculatePointCoordinate(BezierUtils.X_TYPE, fraction, 2, 0, pointList),
                BezierUtils.calculatePointCoordinate(BezierUtils.Y_TYPE, fraction, 2, 0, pointList),
            )
        }

    }
}